package leetcode;

/**    人有生老三千疾，唯有相思不可医。 ——陆游《十二月二日夜梦游沈氏园亭》
 * LeetCode 41 hard 缺失的第一个正数
 * 题意：给你一个未排序的整数数组 nums ，请你找出其中没有出现的最小的正整数。
 * 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
 * 示例 1：
 * 输入：nums = [1,2,0]
 * 输出：3
 *
 * 示例 2：
 * 输入：nums = [7,8,9,11,12]
 * 输出：1
 */
public class LCode41 {
    public static void main(String[] args) {
        int[] nums = {1,2,0};
        int i = firstMissingPositive(nums);
        System.out.println(i);
    }

    /**
     *  解题思路，将各个数组归位，令nums[0] = 1, nums[1] = 2这种。
     *  所以分为两步，第一步就是归位
     *  第二步是 检查nums[i] == i + 1,如果false，说明i + 1缺失。如果数组都不缺失，返回len + 1。
     * @param nums
     * @return
     */
    public static int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; i++) {
            // 如果当前值在1-n范围内，说明都有归宿。如果nums[nums[i] - 1] != nums[i],说明没有归位，让他归位。
            while (nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
                swap(nums,nums[i] - 1,i);
            }
        }
        for (int i = 0; i < n; i++) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return n + 1;
    }
    public static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
